package com.lm.controller;


import com.lm.model.CheckCode;
import com.lm.model.LmUserLogin;
import com.lm.service.CheckCodeService;
import com.lm.service.LmUserLoginService;
import com.lm.utils.ConfigUtil;
import com.meirengu.common.RedisClient;
import com.meirengu.common.StatusCode;
import com.meirengu.controller.BaseController;
import com.meirengu.model.Result;
import com.meirengu.utils.StringUtil;
import com.meirengu.utils.ValidatorUtil;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

@RestController
public class CheckCodeController extends BaseController {
    @Autowired
    CheckCodeService checkCodeService;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private LmUserLoginService lmUserLoginService;

    private static final Logger logger = LoggerFactory.getLogger(CheckCodeController.class);


    /**
     * 获取验证码
     *
     * @param phone
     * @param ip
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "check_code", method = RequestMethod.GET)
    public Result create(@RequestParam(value = "phone", required = true) String phone,
                         @RequestParam(value = "ip", required = false, defaultValue = "127.0.0.1") String ip,
                         @RequestParam(value = "type", required = true) String type) {
        try {
            //verify params
            if (StringUtils.isEmpty(phone) || !ValidatorUtil.isMobile(phone)) {
                return setResult(StatusCode.MOBILE_FORMAT_ERROR, null, StatusCode.codeMsgMap.get(StatusCode.MOBILE_FORMAT_ERROR));
            }
            // 找回登陆密码  找回交易密码 需要判断用户是否注册
            String codeType = ConfigUtil.getConfig("BACK_CODE_FOR_LOGIN");
            if (codeType.equals(type)) {
                //验证手机号是否注册
                LmUserLogin user = lmUserLoginService.detailByPhone(phone);
                if (StringUtil.isEmpty(user)) {
                    return super.setResult(StatusCode.USER_NOT_EXITS, null, StatusCode.codeMsgMap.get(StatusCode.USER_NOT_EXITS));
                }
            }
            int code = checkCodeService.generate();
            logger.info("验证码" + code);
            Result hr = checkCodeService.singleSend(phone, code, ip, type);
            if (hr != null) {
                logger.info("checkCodeService.send <===StatusCode:{}, Content:{}, Response:{}", hr.getCode());
                if (hr.getCode() == StatusCode.OK) {
                    //store db
                    redisClient.set("register_" + phone, code + "", 36000);
                    redisClient.set(type + "_" + phone, "have been send !", 60);
                    CheckCode checkCode = new CheckCode();
                    checkCode.setMobile(phone);
                    checkCode.setCode(code);
                    Date nowTime = new Date();
                    Date expireTime = new Date(nowTime.getTime() + Long.valueOf(ConfigUtil.getConfig("EXPIRE_CHECKCODE_LOGIN")));
                    checkCode.setCreateTime(nowTime);
                    checkCode.setExpireTime(expireTime);
                    checkCode.setIp(StringUtils.defaultString(ip, ""));
                    checkCode.setUse(false);
                    int createResult = checkCodeService.create(checkCode);
                    logger.info("checkCodeService.create result <==={}", createResult);
                    return super.setResult(StatusCode.OK, null, StatusCode.codeMsgMap.get(StatusCode.OK));
                }
            }
            return super.setResult(StatusCode.CHECK_CODE_SEND_ERROR, "短信发送错误", StatusCode.codeMsgMap.get(StatusCode.CHECK_CODE_SEND_ERROR));
        } catch (Exception e) {
            e.printStackTrace();
            String params = String.format("参数:phone:%s,type:%s", phone, type);
            logger.error("checkCodeService.send check_code throws Exceprion :{} happens. params:{}.", ExceptionUtils.getFullStackTrace(e), params);
            return super.setResult(StatusCode.INTERNAL_SERVER_ERROR, e.getMessage(), StatusCode.codeMsgMap.get(StatusCode.INTERNAL_SERVER_ERROR));
        }

    }

    /**
     * 校验验证码有效性
     *
     * @param phone
     * @param checkCode
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "vitify_code", method = RequestMethod.POST)
    public Result vitifyCode(@RequestParam(value = "phone", required = true) String phone,
                             @RequestParam(value = "check_code", required = true) String checkCode) {
        logger.info("CheckCodeController.vitifyCode params >> mobile:{} checkCode:{}", phone, checkCode);
        try {
            //verify params
            if (StringUtils.isEmpty(phone) || !ValidatorUtil.isMobile(phone)) {
                return setResult(StatusCode.MOBILE_FORMAT_ERROR, null, StatusCode.codeMsgMap.get(StatusCode.MOBILE_FORMAT_ERROR));
            }
//            String redisCode = "";
            String redisCode = redisClient.get("register_" + phone);
            logger.info("redisCode <==={}", redisCode);
            //先从redis中认证
            if (StringUtils.isNotBlank(redisCode)) {
                logger.debug("redis store:{} code:{}", checkCode, checkCode);
                if (checkCode.equals(redisCode)) {
                    return super.setResult(StatusCode.OK, null, StatusCode.codeMsgMap.get(StatusCode.OK));
                } else {
                    return super.setResult(StatusCode.CAPTCHA_INVALID, null, StatusCode.codeMsgMap.get(StatusCode.CAPTCHA_INVALID));
                }
            } else {
                CheckCode code = checkCodeService.retrieve(phone, Integer.valueOf(checkCode));
                if (code == null) {
                    return super.setResult(StatusCode.CAPTCHA_INVALID, null, StatusCode.codeMsgMap.get(StatusCode.CAPTCHA_INVALID));
                }
                if (code.getExpireTime().compareTo(new Date()) < 0) {
                    return super.setResult(StatusCode.CAPTCHA_EXPIRE, null, StatusCode.codeMsgMap.get(StatusCode.CAPTCHA_EXPIRE));
                }
            }
            return super.setResult(StatusCode.OK, null, StatusCode.codeMsgMap.get(StatusCode.OK));
        } catch (Exception e) {
            String params = String.format("参数:phone:%s,type:%s", phone, checkCode);
            logger.error("CheckCodeController.vitifyCode throws Exceprion :{} happens. params:{}.", ExceptionUtils.getFullStackTrace(e), params);
            return super.setResult(StatusCode.INTERNAL_SERVER_ERROR, null, StatusCode.codeMsgMap.get(StatusCode.INTERNAL_SERVER_ERROR));
        }
    }
}
